/**
 * 
 */
package juf.adapter;


import java.awt.Component;
import java.awt.Dimension;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

import juf.adapter.jcalendarbutton.*; //the 3rd-party JCalendarButton control
import javax.swing.*;

import juf.Property;


/** Binding between a date-picker style component and a Property data source.
 * 
 * TODO should this be limited to date, time, or both?
 * 
 * <br/>
 * Implemented using the open-source JCalendarButton date picker control from
 * <a href="http://jcalendarbutton.sourceforge.net">jcalendarbutton.sourceforge.net</a>
 * <hr/>
 * JCalendarButton is a simple java swing component that displays a popup calendar when a user click the calendar icon next to a date.
 * It is released under the GPL3 License. Don <don@donandann.com>
 * <hr/>
 * I have added icons for back and forward, and changed the calendar icon - Dale
 * 
 * @author Dale Halliwell
 *
 */
@SuppressWarnings("serial")
public class JDatePickerAdapter extends AbstractAdapter implements Adapter {
	
	public static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
	public static DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
	public static DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);

	private JCalendarButton calendarButton;
	private JTextField textfieldDate;
	
	public JDatePickerAdapter(Property property) {
		//this textfield displays the date
		textfieldDate = new JTextField(); 
		textfieldDate.setColumns(10);		
		textfieldDate.addFocusListener(new java.awt.event.FocusAdapter() { //when focus changes on the text field
            public void focusLost(java.awt.event.FocusEvent evt) {
                dateFocusLost(evt);
            }
        });
		//calendar button, when clicked, opens the date picker
		this.calendarButton = new JCalendarButton();//create the calendar button which displays the date picker		
		this.calendarButton.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) { //when the calendar's value changes
                datePopupChanged(evt); 
            }
        });
			
		//this component is actually a jpanel containing the date textbox (the real 'data component') and calendar button to change its value
		this.component = new JPanel();
		((JPanel) this.component).setLayout(new BoxLayout(((JPanel) this.component), BoxLayout.X_AXIS));
		((JPanel) this.component).add(textfieldDate);	
		((JPanel) this.component).add(Box.createRigidArea(new Dimension(5,0)));
		((JPanel) this.component).add(calendarButton);
		
		bind(property, new Dimension(350,30)); //set up the binding between this and the object
	
	}


	/**
	 * Returns the text field displaying the date
	 * @return textbox bound to the Date object
	 */
	@Override
	public Component getDataComponent(){
		return (Component) this.textfieldDate;
	}
	
	
    /** Invoked by the FocusListener on the JTextField component
     * (Want to update the calendar whent the text value is changed directly)
     * @param evt
     */
    private void dateFocusLost(java.awt.event.FocusEvent evt) {
        String date = this.textfieldDate.getText();
        setDate(date); //get the text and set the date
    }
    
    /** Invoked by the PropertyChangeListener on the JCalendarButton component
     * (Update the textfield when the user selects a new value in the calendar)
     * @param evt
     */
    private void datePopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_datePopupChanged
        if (evt.getNewValue() instanceof Date)
            setDate((Date)evt.getNewValue());
    }
    
	/* (non-Javadoc)
	 * @see juf.adapter.Adapter#refresh()
	 */
	public void refresh() {
		this.clearInvalidWarning();
		if (!(property.getValue() == null))
			setDate((Date) property.getValue()); //get the date value from the object
	}


	/* (non-Javadoc)
	 * @see juf.adapter.Adapter#save()
	 */
	public void save() throws ParseException {	
		property.setValue(dateFormat.parse(this.textfieldDate.getText()));

	}
	
	
	/* (non-Javadoc)
	 * @see adapters.Adapter#validateField()
	 */
	@Override	
	public boolean validateField(){
		try {
			dateFormat.parse(this.textfieldDate.getText());
			this.clearInvalidWarning(); //clear any invalid warning from before
		} catch (ParseException e) {
			this.showInvalidWarning();//show the invalid warning
			//System.out.println("Date could not be parsed correctly\nSee trace below:");
			//e.printStackTrace();
			return false;
		}
		return true;
	}


    /**
     * Validate and set the datetime field on the screen given a datetime string.
     * @param dateTime The datetime string
     */
    protected void setDate(String dateString)
    {
		Date date = null;
		try	{
            if ((dateString != null) && (dateString.length() > 0))
                date = dateFormat.parse(dateString);
		} catch (Exception e)	{
            date = null;
		}
        this.setDate(date);
    }
    /**
     * Validate and set the datetime field on the screen given a date.
     * @param dateTime The datetime object
     */
    protected void setDate(Date date)
    {
        String dateString = "";
        if (date != null) dateString = dateFormat.format(date);
        this.textfieldDate.setText(dateString); //set the text to the date, formatted as a date
        this.calendarButton.setTargetDate(date); //set the calendar's date to the same
    }
    
    
//-----------------------------For using a time, or date-time picker control ---------------------------    
//    /**
//     * Validate and set the datetime field on the screen given a datetime string.
//     * @param dateTime The datetime string
//     */
//    public void setTime(String timeString)
//    {
//		Date time = null;
//		try	{
//            if ((timeString != null) && (timeString.length() > 0))
//                time = timeFormat.parse(timeString);
//		} catch (Exception e)	{
//            time = null;
//		}
//        this.setTime(time);
//    }
//    /**
//     * Validate and set the datetime field on the screen given a date.
//     * @param dateTime The datetime object
//     */
//    public void setTime(Date time)
//    {
//        String timeString = "";
//        if (time != null)
//    		timeString = timeFormat.format(time);
//        jTextField3.setText(timeString);
//        jTimeButton1.setTargetDate(time);
//    }
//    /**
//     * Validate and set the datetime field on the screen given a datetime string.
//     * @param dateTime The datetime string
//     */
//    public void setDateTime(String dateTimeString)
//    {
//		Date dateTime = null;
//		try	{
//            if ((dateTimeString != null) && (dateTimeString.length() > 0))
//                dateTime = dateTimeFormat.parse(dateTimeString);
//		} catch (Exception e)	{
//            dateTime = null;
//		}
//        this.setDateTime(dateTime);
//    }
//    /**
//     * Validate and set the datetime field on the screen given a date.
//     * @param dateTime The datetime object
//     */
//    public void setDateTime(Date dateTime)
//    {
//        String dateTimeString = "";
//        if (dateTime != null)
//    		dateTimeString = dateTimeFormat.format(dateTime);
//        jTextField4.setText(dateTimeString);
//        jCalendarButton2.setTargetDate(dateTime);
//        jTimeButton2.setTargetDate(dateTime);
//    }
	
}
